home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hot Super Models
/
Hot Super Models.iso
/
unix
/
x11
/
xv200.tar
/
xv-2.00
/
xvctrl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-02
|
19KB
|
640 lines
/*
* xvctrl.c - Control box handling functions
*
* callable functions:
*
* CreateCtrl(geom) - creates the ctrlW window. Doesn't map it.
* CtrlBox(vis) - random processing based on value of 'vis'
* maps/unmaps window, etc.
* RedrawCtrl(x,y,w,h) - called by 'expose' events
* ClickCtrl(x,y)
* DrawCtrlStr() - called to redraw 'ISTR_INFO' string in ctrlW
* ScrollToCurrent() - called when 'curname' is changed
*
* LSCreate() - creates a listbox
* LSRedraw() - redraws 'namelist' box
* LSClick() - operates list box
* LSNewData() - called when strings or number of them change
* LSKey() - called to handle page up/down, arrows
*
*/
/*
* Copyright 1989, 1990, 1991, 1992 by John Bradley and
* The University of Pennsylvania
*
* Permission to use, copy, and distribute for non-commercial purposes,
* is hereby granted without fee, providing that the above copyright
* notice appear in all copies and that both the copyright notice and this
* permission notice appear in supporting documentation.
*
* The software may be modified for your own purposes, but modified versions
* may not be distributed.
*
* This software is provided "as is" without any expressed or implied warranty.
*
* The author may be contacted via:
* US Mail: John Bradley
* GRASP Lab, Room 301C
* 3401 Walnut St.
* Philadelphia, PA 19104
*
* Phone: (215) 898-8813
* EMail: bradley@cis.upenn.edu
*/
#include "xv.h"
#include "bitmaps.h"
#define DBLCLKTIME 500 /* double-click speed in milliseconds */
#define INACTIVE(lptr, item) ((lptr)->filetypes && (lptr)->dirsonly && \
(item) >= 0 && (item) < (lptr)->nstr && \
(lptr)->str[(item)][0] != C_DIR && \
(lptr)->str[(item)][0] != C_LNK)
#define NLINES 9 /* # of lines in list control (keep odd) */
#define LISTW CTRL_LISTW
#define BUTTW 71 /* must be odd for 'half' buttons to work out */
#define BUTTH 24
static int listh; /* height of list/scrl controls */
static int ptop; /* y-coord of top of button area in ctrlW */
static Pixmap fifoPix, chrPix, dirPix, blkPix, lnkPix, sockPix, regPix;
static Pixmap rotlPix, rotrPix;
static XRectangle butrect;
static char *dispMList[] = { "Window",
"Root: tiled",
"Root: integer tiled",
"Root: mirrored",
"Root: integer mirrored",
"Root: center tiled",
"Root: centered",
"Root: centered, warp",
"Root: centered, brick" };
#ifdef __STDC__
static void drawSel(LIST *, int);
static void RedrawNList(void);
#else
static void drawSel(), RedrawNList();
#endif
/***************************************************/
void CreateCtrl(geom)
char *geom;
{
int i,b2wide;
XClassHint classh;
CARD32 data[2];
Atom prop;
ctrlW = CreateWindow("xv controls", geom, CTRLWIDE,CTRLHIGH,infofg,infobg);
if (!ctrlW) FatalError("can't create controls window!");
classh.res_name = "xv";
classh.res_class = "XVcontrols";
XSetClassHint(theDisp, ctrlW, &classh);
data[0] = (CARD32)XInternAtom(theDisp, "WM_DELETE_WINDOW", FALSE);
data[1] = (CARD32)time((long *)0);
prop = XInternAtom(theDisp, "WM_PROTOCOLS", FALSE),
XChangeProperty(theDisp, ctrlW, prop, prop,
32, PropModeReplace, (unsigned char *) data, 2);
grayTile = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray25_bits,
gray25_width, gray25_height, infofg, infobg, dispDEEP);
grayStip = XCreatePixmapFromBitmapData(theDisp, ctrlW, gray50_bits,
gray50_width, gray50_height, 1, 0, 1);
fifoPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_fifo_bits,
i_fifo_width, i_fifo_height, 1, 0, 1);
chrPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_chr_bits,
i_chr_width, i_chr_height, 1,0,1);
dirPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_dir_bits,
i_dir_width, i_dir_height, 1,0,1);
blkPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_blk_bits,
i_blk_width, i_blk_height, 1,0,1);
lnkPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_lnk_bits,
i_lnk_width, i_lnk_height, 1,0,1);
sockPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_sock_bits,
i_sock_width, i_sock_height, 1,0,1);
regPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, i_reg_bits,
i_reg_width, i_reg_height, 1,0,1);
rotlPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, h_rotl_bits,
h_rotl_width, h_rotl_height, 1, 0, 1);
rotrPix = XCreatePixmapFromBitmapData(theDisp, ctrlW, h_rotr_bits,
h_rotr_width, h_rotr_height, 1, 0, 1);
if (ctrlColor) XSetWindowBackground(theDisp, ctrlW, locol);
else XSetWindowBackgroundPixmap(theDisp, ctrlW, grayTile);
/* create doo-wahs */
listh = LINEHIGH * NLINES;
LSCreate(&nList, ctrlW, 10, 10+CHIGH+1, LISTW, listh, NLINES, dispnames,
numnames, infofg, infobg, RedrawNList, 0, 0);
nList.selected = 0; /* default to first name selected */
i = listh-BUTTH;
BTCreate(&but[BNEXT], ctrlW, 298, 12+nList.y+(i*1)/8, 60,
BUTTH, "Next", infofg, infobg);
BTCreate(&but[BPREV], ctrlW, 298, 12+nList.y+(i*3)/8, 60,
BUTTH, "Previous", infofg, infobg);
BTCreate(&but[BINFO], ctrlW, 298, 12+nList.y+(i*5)/8, 60,
BUTTH, "Info", infofg, infobg);
BTCreate(&but[BGAMMA], ctrlW,298, 12+nList.y+(i*7)/8, 60,
BUTTH, "ColEdit", infofg, infobg);
BTCreate(&but[BLOAD], ctrlW, 368, 12+nList.y+(i*1)/8, 60,
BUTTH, "Load", infofg, infobg);
BTCreate(&but[BSAVE], ctrlW, 368, 12+nList.y+(i*3)/8, 60,
BUTTH, "Save", infofg, infobg);
BTCreate(&but[BDELETE], ctrlW, 368, 12+nList.y+(i*5)/8, 60,
BUTTH, "Delete", infofg, infobg);
BTCreate(&but[BQUIT], ctrlW, 368, 12+nList.y+(i*7)/8, 60,
BUTTH, "Quit", infofg, infobg);
#define BXSPACE (BUTTW+1)
#define BYSPACE (BUTTH+1)
ptop = CTRLHIGH - (3*BYSPACE + 5 + 4);
#define BX0 ((CTRLWIDE - (BXSPACE*6))/2)
#define BX1 (BX0 + BXSPACE)
#define BX2 (BX0 + BXSPACE*2)
#define BX3 (BX0 + BXSPACE*3)
#define BX4 (BX0 + BXSPACE*4)
#define BX5 (BX0 + BXSPACE*5)
#define BY0 (ptop+5)
#define BY1 (BY0 + BYSPACE)
#define BY2 (BY0 + BYSPACE*2)
butrect.x = BX0-1; butrect.y = BY0-1;
butrect.width = 6*BXSPACE + 1;
butrect.height = 3*BYSPACE + 1;
BTCreate(&but[BCROP], ctrlW,BX0,BY0,BUTTW,BUTTH,"Crop", infofg,infobg);
BTCreate(&but[BUNCROP], ctrlW,BX0,BY1,BUTTW,BUTTH,"UnCrop", infofg,infobg);
BTCreate(&but[BACROP], ctrlW,BX0,BY2,BUTTW,BUTTH,"AutoCrop", infofg,infobg);
BTCreate(&but[BNORM], ctrlW,BX1,BY0,BUTTW,BUTTH,"Normal", infofg,infobg);
BTCreate(&but[BMAX], ctrlW,BX1,BY1,BUTTW,BUTTH,"Max Size", infofg,infobg);
BTCreate(&but[BMAXPECT],ctrlW,BX1,BY2,BUTTW,BUTTH,"Maxpect", infofg,infobg);
BTCreate(&but[BUP2], ctrlW,BX2,BY0,BUTTW,BUTTH,"Dbl Size", infofg,infobg);
BTCreate(&but[BDN2], ctrlW,BX2,BY1,BUTTW,BUTTH,"Half Size",infofg,infobg);
BTCreate(&but[B4BY3], ctrlW,BX2,BY2,BUTTW,BUTTH,"4x3", infofg,infobg);
BTCreate(&but[BUP10], ctrlW,BX3,BY0,BUTTW,BUTTH,"+10%", infofg,infobg);
BTCreate(&but[BDN10], ctrlW,BX3,BY1,BUTTW,BUTTH,"-10%", infofg,infobg);
BTCreate(&but[BASPECT], ctrlW,BX3,BY2,BUTTW,BUTTH,"Aspect", infofg,infobg);
BTCreate(&but[BRAW], ctrlW,BX4,BY0,BUTTW,BUTTH,"Raw", infofg,infobg);
BTCreate(&but[BDITH], ctrlW,BX4,BY1,BUTTW,BUTTH,"Dither", infofg,infobg);
BTCreate(&but[BSMOOTH], ctrlW,BX4,BY2,BUTTW,BUTTH,"Smooth", infofg,infobg);
BTCreate(&but[BROTL], ctrlW,BX5,BY0,BUTTW/2,BUTTH,
"", infofg,infobg);
BTCreate(&but[BROTR], ctrlW,BX5+BUTTW/2 + 1,BY0,BUTTW/2,BUTTH,
"", infofg,infobg);
BTCreate(&but[BFLIPH], ctrlW,BX5,BY1,BUTTW,BUTTH,"Flip H", infofg,infobg);
BTCreate(&but[BFLIPV], ctrlW,BX5,BY2,BUTTW,BUTTH,"Flip V", infofg,infobg);
but[BROTL].pix = rotlPix;
but[BROTL].pw = h_rotl_width;
but[BROTL].ph = h_rotl_height;
but[BROTR].pix = rotrPix;
but[BROTR].pw = h_rotr_width;
but[BROTR].ph = h_rotr_height;
if (numnames<1) BTSetActive(&but[BDELETE],0);
XMapSubwindows(theDisp, ctrlW);
/* have to create dispMB after XMapSubWindows, as we *don't* want the popup
mapped */
MBCreate(&dispMB, ctrlW, 298, but[BNEXT].y - 19 - 8, 128, 19,
"Display Modes", dispMList, RM_MAX+2, infofg, infobg);
if (!useroot) dispMB.selected = 0;
else dispMB.selected = rootMode + 1;
}
/***************************************************/
void CtrlBox(vis)
int vis;
{
if (vis) XMapRaised(theDisp, ctrlW);
else XUnmapWindow(theDisp, ctrlW);
ctrlUp = vis;
}
/***************************************************/
void RedrawCtrl(x,y,w,h)
int x,y,w,h;
{
char foo[40];
int i;
XRectangle xr;
xr.x = x; xr.y = y; xr.width = w; xr.height = h;
XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
XSetForeground(theDisp, theGC, infofg);
XSetBackground(theDisp, theGC, infobg);
XDrawLine(theDisp, ctrlW, theGC, 0, ptop, CTRLWIDE, ptop);
if (numnames != 1) sprintf(foo,"%d files",numnames);
else strcpy(foo,"1 file");
XSetForeground(theDisp, theGC, infobg);
XFillRectangle(theDisp,ctrlW, theGC, 10+1,5+1,StringWidth(foo)+4,CHIGH+2);
XSetForeground(theDisp,theGC,infofg);
XDrawRectangle(theDisp,ctrlW, theGC, 10,5,StringWidth(foo)+5,CHIGH+3);
XDrawString(theDisp, ctrlW, theGC, 10+3, 5+ASCENT+2,
foo, strlen(foo));
XSetForeground(theDisp,theGC,infofg);
XDrawRectangles(theDisp, ctrlW, theGC, &butrect, 1);
for (i=0; i<NBUTTS; i++)
BTRedraw(&but[i]);
MBRedraw(&dispMB);
DrawCtrlStr();
XSetClipMask(theDisp, theGC, None);
}
/***************************************************/
void DrawCtrlStr()
{
int y;
char *st,*st1;
y = ptop - (CHIGH + 4)*2 - 2;
st = GetISTR(ISTR_INFO);
st1 = GetISTR(ISTR_WARNING);
XSetForeground(theDisp, theGC, infobg);
XFillRectangle(theDisp, ctrlW, theGC, 0, y+1, CTRLWIDE, (CHIGH+4)*2+1);
XSetForeground(theDisp, theGC, infofg);
XDrawLine(theDisp, ctrlW, theGC, 0, y, CTRLWIDE, y);
XDrawLine(theDisp, ctrlW, theGC, 0, y+2, CTRLWIDE, y+2);
XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+4, CTRLWIDE, y+CHIGH+4);
XDrawLine(theDisp, ctrlW, theGC, 0, y+CHIGH+6, CTRLWIDE, y+CHIGH+6);
XDrawLine(theDisp, ctrlW, theGC, 0, y+(CHIGH+4)*2, CTRLWIDE, y+(CHIGH+4)*2);
XDrawString(theDisp, ctrlW, theGC, 10, y+ASCENT+3, st, strlen(st));
XDrawString(theDisp, ctrlW, theGC, 10, y+ASCENT+CHIGH+7, st1, strlen(st1));
}
/***************************************************/
int ClickCtrl(x,y)
int x,y;
{
BUTT *bp;
int i;
for (i=0; i<NBUTTS; i++) {
bp = &but[i];
if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
}
if (i<NBUTTS) { /* found one */
if (BTTrack(bp)) return (i); /* and it was clicked */
}
return -1;
}
/***************************************************/
void ScrollToCurrent(lst)
LIST *lst;
{
/* called when 'curname' is changed by anything (next/prev buttons,
wait timeout, whatever. IF curname is already visible, just redraws
list to reflect changed selection. If not, trys to adjust 'liststart'
so that curname will appear in the center of the list window */
int halfway;
if (lst->selected > lst->scrl.val &&
lst->selected < lst->scrl.val + lst->nlines-1) LSRedraw(lst);
else {
halfway = (lst->nlines)/2; /* offset to the halfway pt. of the list */
if (!SCSetVal(&lst->scrl, lst->selected - halfway)) LSRedraw(lst);
}
}
/***************************************************/
static void RedrawNList()
{
LSRedraw(&nList);
}
/***************** LIST STUFF *********************/
/***************************************************/
void LSCreate(lp, win, x, y, w, h, nlines, strlist, nstr, fg, bg, fptr,
typ, donly)
LIST *lp;
Window win;
int x,y,w,h,nlines,nstr,typ,donly;
unsigned long fg, bg;
char **strlist; /* a pointer to a list of strings */
void (*fptr)();
{
lp->win = XCreateSimpleWindow(theDisp,win,x,y,w,h,1,infofg,infobg);
if (!lp->win) FatalError("can't create list window!");
lp->x = x; lp->y = y;
lp->w = w; lp->h = h;
lp->fg = fg; lp->bg = bg;
lp->str = strlist;
lp->nstr = nstr;
lp->selected = -1; /* no initial selection */
lp->nlines = nlines;
lp->filetypes= typ;
lp->dirsonly = donly;
XSelectInput(theDisp, lp->win, ExposureMask | ButtonPressMask);
SCCreate(&lp->scrl, win, x+w, y, 1, h, 0, nstr-nlines, curname, nlines-1,
fg, bg, fptr);
}
/***************************************************/
void LSNewData(lp, strlist, nstr)
LIST *lp;
char **strlist;
int nstr;
{
lp->str = strlist;
lp->nstr = nstr;
lp->selected = -1; /* no initial selection */
SCSetRange(&lp->scrl, 0, nstr - lp->nlines, 0, lp->nlines-1);
}
/***************************************************/
static void drawSel(lp,j)
LIST *lp;
int j;
{
int i, inactive;
unsigned long fg, bg;
inactive = INACTIVE(lp,j);
i = j - lp->scrl.val;
if (i<0 || i>=lp->nlines) return; /* off screen */
if (j == lp->selected && !inactive && j<lp->nstr)
{ fg = lp->bg; bg = lp->fg; } /* invert */
else { fg = lp->fg; bg = lp->bg; }
XSetForeground(theDisp, theGC, bg);
XFillRectangle(theDisp, lp->win, theGC, 0,i*LINEHIGH, lp->w, LINEHIGH);
if (j>=0 && j<lp->nstr) { /* only draw string if valid */
/* make non-dirs inactive, if dirsonly and filetypes */
XSetForeground(theDisp, theGC, fg);
XSetBackground(theDisp, theGC, bg);
if (!lp->filetypes)
XDrawString(theDisp, lp->win, theGC, 3, i*LINEHIGH + ASCENT + 1,
lp->str[j], strlen(lp->str[j]));
else {
int ypos = i*LINEHIGH + (LINEHIGH - i_fifo_height)/2;
if (lp->str[j][0] == C_FIFO)
XCopyPlane(theDisp, fifoPix, lp->win, theGC, 0, 0,
i_fifo_width, i_fifo_height, 3, ypos, 1L);
else if (lp->str[j][0] == C_CHR)
XCopyPlane(theDisp, chrPix, lp->win, theGC, 0, 0,
i_chr_width, i_chr_height, 3, ypos, 1L);
else if (lp->str[j][0] == C_DIR)
XCopyPlane(theDisp, dirPix, lp->win, theGC, 0, 0,
i_dir_width, i_dir_height, 3, ypos, 1L);
else if (lp->str[j][0] == C_BLK)
XCopyPlane(theDisp, blkPix, lp->win, theGC, 0, 0,
i_blk_width, i_blk_height, 3, ypos, 1L);
else if (lp->str[j][0] == C_LNK)
XCopyPlane(theDisp, lnkPix, lp->win, theGC, 0, 0,
i_lnk_width, i_lnk_height, 3, ypos, 1L);
else if (lp->str[j][0] == C_SOCK)
XCopyPlane(theDisp, sockPix, lp->win, theGC, 0, 0,
i_sock_width, i_sock_height, 3, ypos, 1L);
else /* lp->str[j][0] == C_REG */
XCopyPlane(theDisp, regPix, lp->win, theGC, 0, 0,
i_reg_width, i_reg_height, 3, ypos, 1L);
XDrawString(theDisp, lp->win, theGC, 3 + i_fifo_width + 3,
i*LINEHIGH + ASCENT + 1,
lp->str[j]+1, strlen(lp->str[j]+1));
}
}
}
/***************************************************/
void LSRedraw(lp)
LIST *lp;
{
int i;
for (i = lp->scrl.val; i < lp->scrl.val + lp->nlines; i++)
drawSel(lp,i);
}
/***************************************************/
int LSClick(lp,ev)
LIST *lp;
XButtonEvent *ev;
{
/* returns '-1' normally. returns 0 -> numnames-1 for a goto */
Window rW, cW;
int rx, ry, x, y, sel, oldsel;
unsigned int mask;
static Time lasttime=0;
static int lastsel = -1;
x = ev->x; y = ev->y;
sel = lp->scrl.val + y/LINEHIGH;
if (sel >= lp->nstr) sel = lp->selected;
/* see if it's a double click */
if (ev->time - lasttime < DBLCLKTIME && sel==lastsel
&& (lp->scrl.val + y/LINEHIGH) < lp->nstr
&& !INACTIVE(lp,sel)) {
return (sel);
}
lasttime = ev->time; lastsel = sel;
/* if not clicked on selected, turn off selected and select new one */
if (sel != lp->selected) {
oldsel = lp->selected;
lp->selected = sel;
drawSel(lp,sel); drawSel(lp,oldsel);
XFlush(theDisp);
}
while (XQueryPointer(theDisp,lp->win,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
if (!(mask & Button1Mask)) break; /* button released */
if (y<0) { /* scroll up in list */
if (lp->scrl.val > lp->scrl.min) {
lp->selected = lp->scrl.val - 1;
SCSetVal(&lp->scrl, lp->scrl.val - 1);
Timer(100);
}
}
else if (y > lp->h) { /* scroll down in list */
if (lp->scrl.val < lp->scrl.max) {
lp->selected = lp->scrl.val + lp->nlines;
if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1;
SCSetVal(&lp->scrl, lp->scrl.val + 1);
Timer(100);
}
}
else {
sel = lp->scrl.val + y/LINEHIGH;
if (sel >= lp->nstr) sel = lp->nstr - 1;
if (sel != lp->selected && sel >= lp->scrl.val &&
sel < lp->scrl.val + lp->nlines) {
/* dragged to another on current page */
oldsel = lp->selected;
lp->selected = sel;
drawSel(lp, sel); drawSel(lp, oldsel);
XFlush(theDisp);
}
}
}
return(-1);
}
/***************************************************/
void LSKey(lp, key)
LIST *lp;
int key;
{
if (key==LS_PAGEUP) SCSetVal(&lp->scrl,lp->scrl.val - (lp->nlines-1));
else if (key==LS_PAGEDOWN) SCSetVal(&lp->scrl,lp->scrl.val + (lp->nlines-1));
else if (key==LS_HOME) SCSetVal(&lp->scrl,lp->scrl.min);
else if (key==LS_END) SCSetVal(&lp->scrl,lp->scrl.max);
else if (key==LS_LINEUP) {
/* if the selected item visible, but not the top line */
if (lp->selected > lp->scrl.val &&
lp->selected <= lp->scrl.val + lp->nlines - 1) {
/* then just move it */
lp->selected--;
drawSel(lp, lp->selected); drawSel(lp, lp->selected+1);
}
/* if it's the top line... */
else if (lp->selected == lp->scrl.val) {
if (lp->selected > 0) {
lp->selected--;
SCSetVal(&lp->scrl, lp->selected);
}
}
/* if it's not visible, put it on the bottom line */
else {
lp->selected = lp->scrl.val + lp->nlines - 1;
if (lp->selected >= lp->nstr) lp->selected = lp->nstr - 1;
drawSel(lp, lp->selected);
}
}
else if (key==LS_LINEDOWN) {
/* if the selected item visible, but not the bottom line */
if (lp->selected >= lp->scrl.val &&
lp->selected < lp->scrl.val + lp->nlines - 1) {
if (lp->selected < lp->nstr-1) {
/* then just move it */
lp->selected++;
drawSel(lp, lp->selected); drawSel(lp, lp->selected-1);
}
}
/* if it's the bottom line... */
else if (lp->selected == lp->scrl.val + lp->nlines - 1) {
if (lp->selected < lp->nstr-1) {
lp->selected++;
SCSetVal(&lp->scrl, lp->scrl.val+1);
}
}
/* if it's not visible, put it on the top line */
else {
lp->selected = lp->scrl.val;
drawSel(lp, lp->selected);
}
}
}